/* 
 * File:   Functions.cpp
 * Author: Fei Fan
 * E-mail: ffinuyasha@sina.com
 * Copyright © 2013 Fei Fan, All Rights Reserved
 */

#include"FileMng.h"


////////////////////////////////////////////////////////////////////////
//
//								功能模块化函数
//
///////////////////////////////////////////////////////////////////////

//在空闲块表中得到一个空块，并返回(块号)

int getVacSects(int sects[], int sectNumToGet, char *terName) {
    int i, j, n, vNum, vacSumNum, sect,maxVacNum,maxLen;
    short num;
    char *tmp, tempFileName[50];
    Zone myZone;

//    FILE *fp;
//    char filename[50];
//    VacantTable VacantBlock;
//    fp = fopen(SecterPath(filename, SECT_VACDIR), "r");
//    fread(&VacantBlock, sizeof (VacantTable), 1, fp);
//    int tempN=VacantBlock.sectNum;
//    printf("%d\n",tempN);
//    for(int tempI=0;tempI<tempN;tempI++) printf("start:%hd      len:%hd\n",VacantBlock.start[tempI],VacantBlock.len[tempI]);
//    fclose(fp);
    
    if (strcmp(terName, "\0")) {
        strcpy(tempFileName, terName);
        strcat(tempFileName, ":/sys/vac");
    } else
        strcpy(tempFileName, "/sys/vac");
    //printf("%s\n",tempFileName);
    vNum = loadFile(tempFileName, RANDW);
    if (vNum == FAIL) {
        printf("load file %s FAILED!\n", tempFileName);
        return FAIL;
    }
    getMemoZone(&myZone);
    num = myZone.openFileMemo[vNum].sectMemo[0][1];
    VacantTable *vTable;
    vTable = (VacantTable*) myZone.strMemo[num];   
    n = vTable->sectNum;
    vacSumNum = 0;
    maxVacNum=0;
    maxLen=vTable->len[0];
  //  printf("%d\n",n);
    for (i = 0; i < n; i++) {
      //  printf("start:%d      len:%d\n",vTable->start[i],vTable->len[i]);
        vacSumNum += vTable->len[i];
        if(vTable->len[i]>maxLen) maxVacNum=i;
    }
//    printf("%d      %d\n",maxVacNum,maxLen);
//    printf("%d      %d",sectNumToGet,vacSumNum);
    if (sectNumToGet > vacSumNum) {
        printf("There is NO ROOM in the harddisk!\n");
        unloadFile(tempFileName);
        return NO_HD_ROOM;
    }
    myZone.openFileMemo[vNum].mod = 1;
    for (i = 0; i < sectNumToGet; i++) {
        sect = vTable->start[maxVacNum];
        sects[i] = sect;
        vTable->start[maxVacNum] = sect + 1;
        vTable->len[maxVacNum] = vTable->len[maxVacNum] - 1;
        if (vTable->len[maxVacNum] == 0) {
            n--;
            vTable->sectNum = n;
            for (j = maxVacNum; j < n; j++) {
                vTable->start[j] = vTable->start[j + 1];
                vTable->len[j] = vTable->len[j + 1];
            }
        }
        //将硬盘上的这个块初始化
        writeBack("-------", sect, terName);
    }
    tmp = (char*) vTable;
    strcpy(myZone.strMemo[num], tmp);
    putMemoZone(&myZone);
    unloadFile(tempFileName);
    return SUCCESS;
}

//把sect块加入空闲块表中（1=succ 0=fail）

int delSects(int sects[], int sectNumToDel,char *terName) {
    int i, j, n, vNum,thisSect;
    short st;
    char *tmp, tempFileName[50];
    short num;
    Zone myZone;

    if (strcmp(terName, "\0")) {
        strcpy(tempFileName, terName);
        strcat(tempFileName, ":/sys/vac");
    } else
        strcpy(tempFileName, "/sys/vac");
    vNum = loadFile(tempFileName, RANDW);
    if (vNum == FAIL) {
        printf("load file %s FAILED!\n", tempFileName);
        return FAIL;
    }
    
    getMemoZone(&myZone);
    num = myZone.openFileMemo[vNum].sectMemo[0][1];
    VacantTable *vTable;
    vTable = (VacantTable*) myZone.strMemo[num];
    myZone.openFileMemo[vNum].mod = 1;
    for(thisSect=0;thisSect<sectNumToDel;thisSect++){
        n = vTable->sectNum;
        for (i = 0; i < n; i++) {
            st = vTable->start[i];
            if (st > sects[thisSect]) {
                if (i > 0) { //此块在第一个空闲块前
                    if (vTable->start[i - 1] + vTable->len[i - 1] == sects[thisSect]) { //此块前是空闲块
                        if (st - sects[thisSect] == 1) { //此块前后是空闲块
                            vTable->len[i - 1] = vTable->len[i - 1] + vTable->len[i] + 1;
                            n--;
                            vTable->sectNum = n;
                            for (j = i; j < n; j++) {
                                vTable->start[j] = vTable->start[j + 1];
                                vTable->len[j] = vTable->len[j + 1];
                            }
                        } else //此块前是空闲块,后不是
                            vTable->len[i - 1] = vTable->len[i - 1] + 1;
                        break;
                    }
                }
                if (st - sects[thisSect] == 1) { //此块后是空闲块,前不是
                    vTable->start[i] = vTable->start[i] - 1;
                    vTable->len[i] = vTable->len[i] + 1;
                } else { //前后都不是空闲块
                    for (j = n; j > i; j--) {
                        vTable->start[j] = vTable->start[j - 1];
                        vTable->len[j] = vTable->len[j - 1];
                    }
                    vTable->start[i] = sects[thisSect];
                    vTable->len[i] = 1;
                    n++;
                    vTable->sectNum = n;
                }
                break;
            }
        }
    }
    tmp = (char*) vTable;
    strcpy(myZone.strMemo[num], tmp);
    putMemoZone(&myZone);
    unloadFile(tempFileName);
    return SUCCESS;
}

int getHeadNode(HeadIndex *headIndex, char *filename) {
    int i;
    for (i = 0; i < INDEX_MAX; i++) {
        if (strcmp(headIndex[i].name, filename) == 0) return i;
    }
    printf("File %s does NOT exist!\n", filename);
    return FAIL;
}

int getMemoNum(char *filename) {
    int i;
    Zone myZone;
    
    getMemoZone(&myZone);
    for (i = 0; i < OPEN_MAX; i++) {
        if (strcmp(myZone.openFileMemo[i].name, filename) == 0)
            return i;
    }
    printf("File %s has NOT been loaded!\n", filename);
    return FAIL;
}


//void loadSects(int inode)
//{       
//    HeadIndex *headIndex;
//    int i,j,size;
//    char filename[50];
//    
//    loadHeadIndex(headIndex);
//    headIndex[inode].size;
//    
//    //插入打开文件表并装入内存
//        while(openedSize+headIndex[inode].size>STRMEMO_MAX||openedSum==OPEN_MAX){
//                printf("TOO MANY files have loaded, please unload some of them!\n");
//                printf("Please input the file name to be unloaded:");
//                cin>>filename;
//                unloadSects(filename);
//        }
//        size=headIndex[inode].size;
//        for(i=0;i<OPEN_MAX;i++){
//                if(openFileMemo[i].access==FAIL){
//                        openedSum++;
//                        strcpy(openFileMemo[i].name,headIndex[inode].name);
//                        openFileMemo[i].access=ACCESS;
//                        openFileMemo[i].mod=0;
//                        openFileMemo[i].loadType=loadType;
//                        openFileMemo[i].size=size;
//                        openFileMemo[i].type=headIndex[inode].type;
//                        for(j=0;j<size;j++){
//                                sect=headIndex[inode].sects[j];
//                                memoNum=loadToMemo(sect);  //装入内存
//                                openFileMemo[i].sectMemo[j][0]=sect;
//                                openFileMemo[i].sectMemo[j][1]=memoNum;
//                        }
//                        break;
//
//                }
//        }
//        return i; 
//
//
//
//}
//
//
//void unloadSects(int inode)
//{
//
//
//
//
//
//}
//


//拆分路径

int isSys(char *filename) {
    int i, m, n;
    n = strlen(filename);
    char name[] = "sys";
    for (i = 1; i < n; i++) {
        if (filename[i] == '/')
            break;
        if (filename[i] != name[i - 1])
            return 0;
    }
    //m=strlen(name);
    if (3 == (i - 1))
        return 1;
    else
        return 0;
}

int isRemote(char *filename, char *terName, char *path) {
    int i, j, n, div;
    n = strlen(filename);
    for (i = 0; i < n; i++) {
        if (filename[i] == ':') {
            div = i;
            terName[i] = '\0';
            i++;
            for (j = 0; i < n; i++, j++) {
                path[j] = filename[i];
            }
            path[j]='\0';
            return SUCCESS;
        }
        terName[i] = filename[i];
    }
    strcpy(terName, "\0");
    return FAIL;
}

void replaceContent(char *stream, int openNum) {
    char filename[50], *p;
    int i, j;
    short memoNum, size;
    Zone myZone;
    
    p = stream;
    getMemoZone(&myZone);
    myZone.openFileMemo[openNum].mod = 1;

    for (i = 0;; i++) {
        if (i == myZone.openFileMemo[openNum].size) {
            while (myZone.openedSize == STRMEMO_MAX) {
                printf("TOO MANY files have loaded, please unload some of them!\n");
                printf("Please input the file name to be unloaded:");
                gets(filename);
                putMemoZone(&myZone);
                unloadFile(filename);
                getMemoZone(&myZone);
            }
            for (j = 0; j < STRMEMO_MAX; j++) {
                if (strcmp(myZone.strMemo[j], "\0") == 0) {
                    myZone.openedSize++;
                    myZone.openFileMemo[openNum].sectMemo[i][1] = j;
                    myZone.openFileMemo[openNum].size++;
                    break;
                }
            }
        }

        memoNum = myZone.openFileMemo[openNum].sectMemo[i][1];
        for (j = 0; j < CONTENT_MAX - 1; j++) {
            if (*p == '\0') {
                myZone.strMemo[memoNum][j] = '\0';
                size = myZone.openFileMemo[openNum].size;
                myZone.openFileMemo[openNum].size = i + 1;
                for (i = i + 1; i < size; i++) {
                    memoNum = myZone.openFileMemo[openNum].sectMemo[i][1];
                    unloadMemo(&myZone,memoNum);
                }
                putMemoZone(&myZone);
                return;
            }
            myZone.strMemo[memoNum][j] = *p;
            p++;
        }
        myZone.strMemo[memoNum][j] = '\0';
    }

}

void appendContent(char *stream, int openNum) {
    char *p, filename[50];
    short memoNum, size;
    int len, i, j, streamLen;
    Zone myZone;

    getMemoZone(&myZone);
    myZone.openFileMemo[openNum].mod = 1;
    size = myZone.openFileMemo[openNum].size;
    memoNum = myZone.openFileMemo[openNum].sectMemo[size - 1][1];
    len = strlen(myZone.strMemo[memoNum]);

    while (1) {
        streamLen = strlen(stream);
        stream[streamLen] = '\0';
        if (streamLen + len >= (SECT_MAX - size + 1) * CONTENT_MAX) {
            printf("The content appending is TOO LONG, please input again:\n");
            gets(stream);
        } else
            break;
    }

    p = stream;
    for (i = len; i < CONTENT_MAX - 1; i++) {
        if (*p == '\0') {
            myZone.strMemo[memoNum][i] = '\0';
            putMemoZone(&myZone);
            return;
        }
        myZone.strMemo[memoNum][i] = *p;
        p++;

    }
    myZone.strMemo[memoNum][i] = '\0';

    for (i = size;; i++) {
        while (myZone.openedSize == STRMEMO_MAX) {
            printf("TOO MANY files have loaded, please unload some of them!\n");
            printf("Please input the file name to be unloaded:");
            gets(filename);
            putMemoZone(&myZone);
            unloadFile(filename);
            getMemoZone(&myZone);
        }
        for (j = 0; j < STRMEMO_MAX; j++) {
            if (strcmp(myZone.strMemo[j], "\0") == 0) {
                myZone.openedSize++;
                myZone.openFileMemo[openNum].sectMemo[i][1] = j;
                myZone.openFileMemo[openNum].size++;
                break;
            }
        }

        memoNum = j;
        for (j = 0; j < CONTENT_MAX - 1; j++) {
            if (*p == '\0') {
                myZone.strMemo[memoNum][j] = '\0';
                myZone.openFileMemo[openNum].size = i + 1;
                putMemoZone(&myZone);
                return;
            }
            myZone.strMemo[memoNum][j] = *p;
            p++;
        }
        myZone.strMemo[memoNum][j] = '\0';
    }

}

void addHead(HeadIndex *headIndex, char *filename, short pms, short sect, short type, short size, long modTime) {
    int i;
    for (i = 0; i < INDEX_MAX; i++) {
        if (headIndex[i].type == TYPE_NONE) {
            strcpy(headIndex[i].name, filename);
            headIndex[i].PMS = pms;
            headIndex[i].sects[0] = sect;
            headIndex[i].type = type;
            headIndex[i].size = size;
            headIndex[i].modTime = modTime;
            headIndex[i].rdCnt = 0;
            headIndex[i].wrtCnt = 0;
            break;
        }
    }
}

void delFileInDir(int dirOpenNum, char *file) {
    char stream[CONTENT_MAX], line[50];
    char *p, *q;
    int i, j, n, openNum, flag;
    short size, memoNum;
    Zone myZone;

    getMemoZone(&myZone);
    openNum = dirOpenNum;
    myZone.openFileMemo[openNum].mod = 1;
    size = myZone.openFileMemo[openNum].size;
    strcpy(stream, "\0");
    for (i = 0; i < size; i++) {
        memoNum = myZone.openFileMemo[openNum].sectMemo[i][1];
        strcat(stream, myZone.strMemo[memoNum]);
    }
    n = strlen(file);
    p = stream + 7;
    while (1) {
        for (i = 0;; i++) {
            if (*(p + i) == '-')
                break;
            else
                line[i] = *(p + i);
        }
        q = p + i + 7;
        line[i] = '\0';
        flag = 0;
        for (i = 0; i < n; i++) {
            if (line[i] != file[i]) {
                flag = 1;
                break;
            }
        }
        if (flag == 0) {
            if (line[i] == '\t') {
                while (*q != '\0') {
                    *p = *q;
                    p++;
                    q++;
                }
                *p = '\0';
                strcpy(myZone.strMemo[memoNum], stream);
                putMemoZone(&myZone);
                return;
            }
        }
        p = q;
    }
    //	unloadFile(dir,name);
    //	return FAIL;
}

void showOpen() {
    Zone myZone;
    
    printf("\n\n--------FILES IN THE MEMORY---------\n");
    getMemoZone(&myZone);
    for (int i = 0; i < OPEN_MAX; i++) {
        if (myZone.openFileMemo[i].access != FAIL)
            printf("%s\n", myZone.openFileMemo[i].name);
    }
    printf("\n\n------------------------------------\n");
}


